package com.witmore.skyline.web.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.witmore.skyline.db.entity.CameraPicDO;
import com.witmore.skyline.db.mapper.CameraPicMapper;
import com.witmore.skyline.web.config.GlobalAccountSession;
import com.witmore.skyline.web.constants.TableSortConstant;
import com.witmore.skyline.web.controller.enums.WitmoreErrorCode;
import com.witmore.skyline.web.controller.vo.param.CameraPicQueryParam;
import com.witmore.skyline.web.controller.vo.result.CameraPicResult;
import com.witmore.skyline.web.controller.vo.result.ResponsePageResult;
import com.witmore.skyline.web.controller.vo.result.ResponseResult;
import com.witmore.skyline.web.service.MessageService;
import com.witmore.skyline.web.service.PictureAnalysisService;
import com.witmore.skyline.web.service.PictureService;
import com.witmore.skyline.web.service.ProjectService;
import com.witmore.skyline.web.service.third.neutronAI.NeutronAIApiChatClient;
import com.witmore.skyline.web.service.third.neutronAI.dto.NeutronResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Description: PictureServiceImpl
 * Author: 豆子高
 * Date: 2025/4/17 17:16
 */
@Slf4j
@Service
public class PictureServiceImpl implements PictureService {

    @Autowired
    private CameraPicMapper cameraPicMapper;

    @Autowired
    private NeutronAIApiChatClient neutronAIApiChatClient;

    @Autowired
    private ProjectService projectService;


    @Autowired
    private MessageService messageService;

    @Autowired
    private PictureAnalysisService pictureAnalysisService;

    @Override
    public ResponsePageResult<CameraPicResult> list(CameraPicQueryParam param) {
        if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(param.getStartTime()) && org.apache.commons.lang3.ObjectUtils.isNotEmpty(param.getEndTime())) {
            // 结束时间不能早于结束时间
            if (param.getStartTime().isAfter(param.getEndTime())) {
                return ResponsePageResult.fail(4001, "开始时间不能晚于结束时间");
            }
            // 时间跨度不能超过一周
            if (ChronoUnit.DAYS.between(param.getStartTime(), param.getEndTime()) > 7) {
                return ResponsePageResult.fail(4003, "时间跨度不能超过一周");
            }
        }
        if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(param.getStartTime())) {
            // 起始时间早于当前时间时 默认为当前时间
            if (param.getStartTime().isAfter(LocalDateTime.now())) {
                param.setStartTime(LocalDateTime.now());
            }
        }
        if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(param.getEndTime())) {
            // 结束时间晚于当前时间时 默认为当前时间
            if (param.getEndTime().isAfter(LocalDateTime.now())) {
                param.setEndTime(LocalDateTime.now());
            }
        }
        // 封装项目id
        Set<Integer> projectIds = new HashSet<>();
        if (param.getProjectId() != null) {
            // 查询当前项目及其子项目的所有项目ID
            List<Integer> projectIdsWithChildren = projectService.getProjectIdsWithChildren(param.getProjectId());
            projectIds.addAll(projectIdsWithChildren);
        }
        // 获取ai等级类型
        List<Integer> aiLevelTypeList = this.getAiLevelTypeList(param.getAiLevelType());
        LambdaQueryWrapper<CameraPicDO> queryWrapper = new LambdaQueryWrapper<CameraPicDO>()
                .eq(null != param.getCameraPicId(), CameraPicDO::getId, param.getCameraPicId())
                .eq(CameraPicDO::getOrgId, GlobalAccountSession.getUserInfo().getOrgId())
                .eq(CameraPicDO::getIsDeleted, 0)
                .eq(StringUtils.isNotEmpty(param.getCameraSn()), CameraPicDO::getCameraSn, param.getCameraSn())
                .eq(StringUtils.isNotEmpty(param.getCameraName()), CameraPicDO::getCameraName, param.getCameraName())
                .eq(StringUtils.isNotEmpty(param.getDeviceName()), CameraPicDO::getDeviceName, param.getDeviceName())
                .eq(StringUtils.isNotEmpty(param.getDeviceSn()), CameraPicDO::getDeviceSn, param.getDeviceSn())
                .eq(param.getSourceType() != null, CameraPicDO::getSourceType, param.getSourceType())
                .eq(param.getStatus() != null, CameraPicDO::getAnalyzeStatus, param.getStatus())
                .in(!CollectionUtils.isEmpty(aiLevelTypeList), CameraPicDO::getAiLevelType, aiLevelTypeList)
                .in(!CollectionUtils.isEmpty(projectIds), CameraPicDO::getProjectId, projectIds)
                // 添加时间查询范围
                .ge(param.getStartTime() != null, CameraPicDO::getCreateTime, param.getStartTime())
                .le(param.getEndTime() != null, CameraPicDO::getCreateTime, param.getEndTime())
                .like(StringUtils.isNotEmpty(param.getAiResult()), CameraPicDO::getAiResult, param.getAiResult())
                ;
        // 排序
        if (StringUtils.isNotEmpty(param.getSortField()) && StringUtils.isNotEmpty(param.getSortOrder())) {
            SFunction<CameraPicDO, ?> cameraPicDOSFunction = TableSortConstant.convertToDbFieldCameraPic(param.getSortField());
            if (param.getSortOrder().equalsIgnoreCase("asc")) {
                queryWrapper.orderByAsc(cameraPicDOSFunction);
            } else {
                queryWrapper.orderByDesc(cameraPicDOSFunction);
            }
        } else {
            queryWrapper.orderByDesc(CameraPicDO::getCreateTime);
        }

        Page<CameraPicDO> cameraPicDOPage = cameraPicMapper.selectPage(new Page<>(param.getPage(), param.getSize()), queryWrapper);
        if (ObjectUtils.isEmpty(cameraPicDOPage)) {
            return ResponsePageResult.fail(WitmoreErrorCode.SYSTEM_ERROR);
        }
        if (CollectionUtils.isEmpty(cameraPicDOPage.getRecords())) {
            return ResponsePageResult.success(new Page<>());
        }
        return ResponsePageResult.success(cameraPicDOPage, resultDTO -> {
                    CameraPicResult cameraPicResult = CameraPicResult.builder().build();
                    BeanUtils.copyProperties(resultDTO, cameraPicResult);
                    cameraPicResult.setStatus(resultDTO.getAnalyzeStatus());
                    cameraPicResult.setAiLevelType(resultDTO.getAiLevelType());
                    return cameraPicResult;
                }
        );
    }


    private List<Integer> getAiLevelTypeList(Integer aiLevelType) {
        // 首先将用户查询的状态放进去
        if (aiLevelType != null) {
            return List.of(aiLevelType);
        } else {
            // AI分析结果
            if ("admin".equals(GlobalAccountSession.getUserInfo().getUserName())) {
                // 超级管理员 可以查看 所有状态的数据
                return null;
            } else {
                // 其他用户 需要过滤无人数据0
                return List.of(1, 2, 3);
            }
        }
    }

    @Override
    public ResponseResult<Void> delete(Integer id) {
        if (null == id) {
            return ResponseResult.fail(WitmoreErrorCode.PARAM_ERROR);
        }
        CameraPicDO cameraPicDO = cameraPicMapper.selectById(id);
        if (null == cameraPicDO) {
            return ResponseResult.fail(WitmoreErrorCode.PARAM_ERROR);
        }
        cameraPicMapper.updateById(CameraPicDO.builder()
                .id(id)
                .isDeleted(1)
                .build());
        return ResponseResult.success();
    }

    @Override
    public ResponseResult<Void> aiCheck(Integer cameraPicId) throws Exception {
        if (null == cameraPicId) {
            return ResponseResult.fail(WitmoreErrorCode.PARAM_ERROR);
        }
        CameraPicDO cameraPicDO = cameraPicMapper.selectById(cameraPicId);
        if (null == cameraPicDO) {
            return ResponseResult.fail(WitmoreErrorCode.PARAM_ERROR);
        }
        CameraPicDO cameraPicUpdate = CameraPicDO.builder()
                .id(cameraPicId)
                .updateTime(LocalDateTime.now())
                .build();

        // 执行人体检测和AI分析
        CameraPicDO analysisResult = pictureAnalysisService.analyzeWithHumanDetection(
                cameraPicDO.getPicUrl(), cameraPicDO.getCameraSn(), "手动AI检查");

        if (analysisResult == null) {
            return ResponseResult.fail(WitmoreErrorCode.SYSTEM_ERROR);
        }

        // 设置分析结果
        cameraPicUpdate.setAnalyzeStatus(analysisResult.getAnalyzeStatus());
        cameraPicUpdate.setAiMessage(analysisResult.getAiMessage());
        cameraPicUpdate.setAiLevel(analysisResult.getAiLevel());
        cameraPicUpdate.setAiLevelType(analysisResult.getAiLevelType());
        cameraPicUpdate.setAiResult(analysisResult.getAiResult());
        cameraPicMapper.updateById(cameraPicUpdate);

        // 只有在有有效AI分析结果时才发送mqtt消息（即aiLevelType != 0）
        if (analysisResult.getAiLevelType() != null && analysisResult.getAiLevelType() != 0) {
            // 发送mqtt
            cameraPicUpdate.setPicUrl(cameraPicDO.getPicUrl());
            cameraPicUpdate.setOrgId(cameraPicDO.getOrgId());
            cameraPicUpdate.setId(cameraPicDO.getId());
            messageService.saveMessage(cameraPicUpdate);
        }
        return ResponseResult.success();
    }

    @Override
    public CameraPicDO neutronChatCompletions(String ossUrl, String cameraSn) throws Exception {
        CameraPicDO cameraPicDOResult = CameraPicDO.builder().build();
        NeutronResult neutronResult = neutronAIApiChatClient.neutronChatCompletions(cameraSn, ossUrl);
        if (neutronResult == null) {
            log.warn("调用AI大模型分析图片失败，摄像头sn：{}，图片地址：{},失败原因:{}", cameraSn, ossUrl, "返回结果为空！");
            return null;
        }
        cameraPicDOResult.setAiMessage(JSONObject.toJSONString(neutronResult));
        cameraPicDOResult.setAnalyzeStatus(1);
        if (neutronResult.getCode() == 200) {
            // 安全、违规
            String level = neutronResult.getLevel();
            cameraPicDOResult.setAiLevel(level);
            if ("安全".equals(level)) {
                cameraPicDOResult.setAiLevelType(1);
            } else if ("违规".equals(level)) {
                cameraPicDOResult.setAiLevelType(2);
            } else {
                cameraPicDOResult.setAiLevelType(3);
            }
            cameraPicDOResult.setAiResult(neutronResult.getContent());
            return cameraPicDOResult;
        } else {
            cameraPicDOResult.setAiLevel("其他");
            cameraPicDOResult.setAiLevelType(3);
            cameraPicDOResult.setAiResult(neutronResult.getContent());
            return cameraPicDOResult;
        }
    }

    @Override
    public ResponseResult<Void> aiCheckCorrect(Integer cameraPicId) {
        // 校验账号 只有 admin 的 账号可以使用
        String userName = GlobalAccountSession.getUserInfo().getUserName();
        if (StringUtils.isEmpty(userName) || !StringUtils.equals(userName, "admin")) {
            return ResponseResult.success();
        }
        CameraPicDO cameraPicDO = cameraPicMapper.selectById(cameraPicId);
        if (null == cameraPicDO) {
            return ResponseResult.success();
        }
        if (null == cameraPicDO.getAnalyzeStatus() || cameraPicDO.getAnalyzeStatus() == 0) {
            return ResponseResult.success();
        }
        if (null == cameraPicDO.getAiLevelType() || cameraPicDO.getAiLevelType() != 2) {
            return ResponseResult.success();
        }
        CameraPicDO cameraPicUpdate = CameraPicDO.builder()
                .id(cameraPicId)
                .aiResult("符合安全规范")
                .aiLevel("安全")
                .aiLevelType(1)
                .updateTime(LocalDateTime.now())
                .build();
        cameraPicMapper.updateById(cameraPicUpdate);
        return ResponseResult.success();
    }
}
